package com.qd.p2p.web.action.user;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Action;

import com.opensymphony.xwork2.ModelDriven;
import com.qdlc.p2p.biz.service.UserService;
import com.qdlc.p2p.biz.service.user.UserRegistService;
import com.qdlc.p2p.biz.util.UserLoginUtil;
import com.qdlc.p2p.biz.util.UserReturnResult;
import com.qdlc.p2p.biz.web.action.BaseAction;
import com.qdlc.p2p.common.constant.UserType;
import com.qdlc.p2p.common.core.PropertyPlaceholderConfigurerHelper;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.exception.UserException;
import com.qdlc.p2p.common.util.DataUtils;
import com.qdlc.p2p.common.util.LogFactory;
import com.qdlc.p2p.common.util.OrderNoUtils;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.common.util.code.BASE64Decoder;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.model.UserModel;

/**
 * 用户注册Action
 * 
 * @author linya 2016-02-01
 */
public class UserRegistAction extends BaseAction<User> implements ModelDriven<User>{

	private static final Logger log = LogFactory.REGIST_LOGGER;
	
	private static final String SESSION_REGIST_USER_MODEL = "regist_user_model";
	
    @Resource
    private UserService userService;
    
    @Resource
    private UserRegistService userRegistService;
	
    /**
     * 注册页面[普通用户注册]
     */
    @Action("/user/register")
    public String register() throws Exception {
        regist();
        return "register";
    }
    
    /**
     * 注册页面[企业用户注册]
     */
    @Action("/user/registcomqd")
    public String registcomqd() throws Exception {
        regist();
        return "registcomqd";
    }
    
    /**
     * 注册页面请求初始化
     * @throws Exception
     */
    private void regist() throws Exception{
    	User user = getSessionUser();
        if (user != null) {
            redirect("/member/main.html");
        }
        //这两个不知道干啥用的!
        request.setAttribute("ui", paramString("ui"));
        request.setAttribute("distinction_type", SystemConfigHelper.getValue(Nid.DISTINCTION_TYPE));
        //RSA初始化(不知道干啥用的!)
        initRSAME();
    }
    
    /**
     * [注册]第一步: 提交基本信息账户
     */
    @Action("/user/registerFirst")
    public void registerFirst() throws IOException {
        
    	//1. 阅读用户注册协议
        if (paramInt("agree") != 1) {
            throw new UserException("请阅读并同意服务协议!", BusinessException.TYPE_JSON);
        }
        
        //2. 获取用户提交注册信息
        UserModel userModel = UserModel.instance(model);
        boolean member = PropertyPlaceholderConfigurerHelper.getBooleanValue("common.test.regist.member");
        if(member){
        	userModel.setUserType(UserType.INVESTMENT_BORROWER);
        }else{
        	userModel.setUserType(paramInt("userType"));
        }
		userModel.setUserNature(paramInt("userNature"));
        userModel.setValidCode(paramString("validCode"));
        userModel.setConfirmNewPwd(paramString("confirmPassword"));
        
        //3. 基本信息检测
        ReturnResult checkResult = userRegistService.checkRegisterBaseInfo(userModel);
        if(checkResult.isError()){
        	printWebResult(checkResult.getErrorInfo(), false);
        	return;
        }
        
        //4. 是否有邀请人，有则设置邀请人Id
        String ui = paramString("ui");
        if (!StringUtils.isBlank(ui)) {
            BASE64Decoder decoder = new BASE64Decoder();
            ui = decoder.decodeStr(ui);
            long uId = DataUtils.toLong(ui);
            if(uId > 0){
            	User inviteUser = userService.find(uId);
            	userModel.setInviteUser(inviteUser);
            }
        }
        
        //5. UserModel写入到session中去
        session.put(SESSION_REGIST_USER_MODEL, userModel);
        
        //6. 写入下一步注册数据
        Map<String, Object> data = new HashMap<String, Object>(2);  

        data.put("mobilePhone", model.getMobilePhone());
        data.put("remain", 0);
        writeSignToken(data);
    
    }
    
    /**
     * [注册]第二步: 获取验证码
     */
    @Action("/user/getPhoneCode")
    public void getPhoneCode() throws IOException {
        
        //1. 检测Sign
        ReturnResult result = checkSignTokenAndUserModel();
        if(result.isError()){
        	printWebResult(result.getErrorInfo(), false, result.toMap());
        	return;
        }
        
        //2. 开始发送注册短信
        UserModel userModel = (UserModel) result.getExtra(SESSION_REGIST_USER_MODEL);
        String mobilePhone = StringUtils.trimToEmpty(paramString("mobilePhone"));
        result = userRegistService.doSendValidCode(userModel, mobilePhone);
        if(result.isError()){
        	printWebResult(result.getErrorInfo(), false, result.toMap());
        	return;
        }
        
        //3. 写入下一步Sign和Token
        writeSignToken(null);
        
    }
    
    
    /**
     * 注册第三步:提交注册
     */
    @Action("/user/doRegister")
    public void doRegister() throws Exception {
        
    	//1. 检测Sign
        ReturnResult result = checkSignTokenAndUserModel();
        if(result.isError()){
        	printWebResult(result.getErrorInfo(), false, result.toMap());
        	return;
        }

        //2. 设置验证码和请求IP，开始注册流程
        UserModel userModel = (UserModel) result.getExtra(SESSION_REGIST_USER_MODEL);
        userModel.setCode(paramString("code"));
        try {
			result = userRegistService.doRegister(userModel, false);
		} catch (Exception e) {
			writeRegistFailure(userModel.getUserName(), e);
		}
        
        if(result instanceof UserReturnResult){
        	removeToken();
        	writeRegistSuccess((UserReturnResult)result);
        }else{
        	writeRegistFailure(userModel.getUserName(), null);
        }
        
    }
    
    /**
     * 处理注册失败
     * @param userName
     * @param e
     */
    private void writeRegistFailure(String userName, Exception e){
    	log.error("++++ 用户" + userName + "注册失败!", e);
		throw new UserException("注册失败！", BusinessException.TYPE_JSON);
    }
    
    /**
     * 处理注册成功，注册成功后缓存登录用户，并跳转到主页面
     * @param result
     */
    private void writeRegistSuccess(UserReturnResult result) throws Exception{
    	User user = result.getUser();
    	log.info(MessageFormat.format("++++ 用户{0}注册成功!", user));
    	UserLoginUtil.cacheLoginUser(user.getUserId());
		result.addExtra("redirectURL", "/member/main.html?activity=register");
		printWebResult("注册成功!", true, result.getExtra());
    }
    
    
    /**
     * 写入Sign和Token信息
     */
    private void writeSignToken(Map<String, Object> extraMap) throws IOException{
    	HashMap<String, Object> data = new HashMap<String, Object>();
    	if(extraMap != null){
    		data.putAll(extraMap);
    	}
    	String sign = OrderNoUtils.getSerialNumber();
        data.put("result", true);
        data.put("sign", sign);
        String token = StringUtil.getMd5Sign(sign);
        session.put("token", token);
        printWebJson(getStringOfJpaObj(data));
    }
    
    /**
     * 1. 检测Sign和Token信息
     * 2. 检测Session中UserModel
     */
    private ReturnResult checkSignTokenAndUserModel(){
        
    	//检测Sign和Token信息
    	String sign = StringUtil.getMd5Sign(paramString("sign"));
        String token = DataUtils.toString(session.get("token"));
        if (!sign.equals(token)) {
            return new ReturnResult("非法提交!");
        }
        
        //检测Session中UserModel
        UserModel userModel = (UserModel) session.get(SESSION_REGIST_USER_MODEL);
        if (userModel == null) {
        	return new ReturnResult("请确认注册信息是否正确!");
        }
        
        ReturnResult result = new ReturnResult();
        result.addExtra(SESSION_REGIST_USER_MODEL, userModel);
        
        return result;
    }
    
    /**
     * 注册成功后删除Token
     */
    private void removeToken(){
    	session.remove("token");
    }
}
